package com.zhichat.web.socket.netty;

import com.zhichat.infrastructure.config.ZhiChatConfig;
import com.zhichat.infrastructure.constants.Constants;
import com.zhichat.web.socket.netty.handler.WsHearBeatHandler;
import com.zhichat.web.socket.netty.handler.WsTextMsgHandler;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.timeout.IdleStateHandler;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

/**
 * @ClassName: WsInitHandler
 * @Description: 初始化netty的handler
 * @Author: 团长九哥 https://space.bilibili.com/602197686
 * @CreateDate: 2024/11/29 21:45
 */
@Slf4j
@Component
@AllArgsConstructor
public class WsInitHandler extends ChannelInitializer<NioSocketChannel> {

    private final WsTextMsgHandler wsTextMsgHandler;
    private final WsHearBeatHandler wsHearBeatHandler;
    private final ZhiChatConfig zhiChatConfig;

    @Override
    protected void initChannel(NioSocketChannel channel) throws Exception {
        ChannelPipeline pipeline = channel.pipeline();
        // 设置 通道处理器（多个）
        // http 编/解 码器
        pipeline.addLast(new HttpServerCodec());
        // http 消息聚合器（保证接受http请求的完整性）
        pipeline.addLast(new HttpObjectAggregator(65536));
        /*
         * 心跳检测（设置心跳规则，超时之后怎么处理）
         *       1. 读空闲时间 60s - 建立连接时，超过60秒没有发送读请求，执行读超时逻辑（new HearBeatHandler()超时处理逻辑）
         *       2. 写空闲时间 0s
         *       3. 读写空闲时间 0s
         */
        pipeline.addLast(new IdleStateHandler(Constants.READER_IDLE_TIME, 0, 0));
        // 心跳处理器（匹配设置的规则，去处理满足规则的事件）
        pipeline.addLast(wsHearBeatHandler);
        /*
         * websocket 协议处理器
         *      1. /ws 请求路径
         *      2. null 子协议
         *      3. true 允许跨域
         *      4. 65536 最大内容长度
         */
//                        pipeline.addLast(new WebSocketServerProtocolHandler("/ws", null, true, 65536));
        pipeline.addLast(new WebSocketServerProtocolHandler(zhiChatConfig.getWsContextPath(), null, true,
                65536, true, true));
        // 文本处理器（收到消息，处理消息）
        pipeline.addLast(wsTextMsgHandler);
    }
}
